Qtize rgbcolors. (#1356)
authortsteven4 <13596209+tsteven4@users.noreply.github.com>
Tue, 22 Oct 2024 14:09:51 +0000 (08:09 -0600)
committerGitHub <noreply@github.com>
Tue, 22 Oct 2024 14:09:51 +0000 (08:09 -0600)
* Qtize rgbcolors.

* use big stick to validate hex color codes

defs.h
ozi.cc
rgbcolors.cc
testo.d/ozi.test

diff --git a/defs.h b/defs.h
index 5a274924353f3e83baf0a2bb148dd6bc4a40e4f4..ac8c54382fc802d1c3d4136bb2090f7948f792f8 100644 (file)
--- a/defs.h
+++ b/defs.h
@@ -1037,7 +1037,7 @@ int parse_speed(const QString& str, double* val, double scale, const char* modul
 /*
  * Color helpers.
  */
-int color_to_bbggrr(const char* cname);
+int color_to_bbggrr(const QString& cname);
 
 /*
  * A constant for unknown altitude.   It's tempting to just use zero
diff --git a/ozi.cc b/ozi.cc
index 1c156e3e6cd975452722ff3e08ff27ec9bb0c0e7..283c5f4cda8652f64aea8ff5fc63d57124673914 100644 (file)
--- a/ozi.cc
+++ b/ozi.cc
@@ -96,8 +96,8 @@ OziFormat::ozi_alloc_fsdata()
   auto* fsdata = new ozi_fsdata;
 
   /* Provide defaults via command line defaults */
-  fsdata->fgcolor = color_to_bbggrr(wptfgcolor);
-  fsdata->bgcolor = color_to_bbggrr(wptbgcolor);
+  fsdata->fgcolor = color_to_bbggrr(wptfgcolor.get());
+  fsdata->bgcolor = color_to_bbggrr(wptbgcolor.get());
 
   return fsdata;
 }
index a82fa3f8b02d211ccff140a7d6fe157f4773c99b..564c659d33662d4e090472b611e3377982deb3a4 100644 (file)
@@ -1,7 +1,7 @@
 /*
     Color utilities.
 
-    Copyright (C) 2005 Robert Lipe, robertlipe+source@gpsbabel.org
+    Copyright (C) 2005,2024 Robert Lipe, robertlipe+source@gpsbabel.org
 
     This program is free software; you can redistribute it and/or modify
     it under the terms of the GNU General Public License as published by
 
  */
 
-#include "defs.h"
-#include <cstdlib>
+#include <assert.h>            // for assert
+
+#include <QByteArray>          // for QByteArray
+#include <QHash>               // for QHash
+#include <QRegularExpression>  // for QRegularExpression, QRegularExpressionMatch
+#include <QString>             // for QString, QTypeInfo<>::isRelocatable
+#include <QtGlobal>            // for qPrintable
+
+#include "defs.h"              // for fatal, color_to_bbggrr
 
 /*
  * Colors derived from http://www.w3.org/TR/SVG/types.html#ColorKeywords
  * same colors supported by X11.
  */
 
-static const struct {
-  const char* cn;
+struct rgb_t {
   unsigned char r;
   unsigned char g;
   unsigned char b;
-} color_table[] = {
-  {"aliceblue", 240, 248, 255},
-  {"antiquewhite", 250, 235, 215},
-  {"aqua",  0, 255, 255},
-  {"aquamarine", 127, 255, 212},
-  {"azure", 240, 255, 255},
-  {"beige", 245, 245, 220},
-  {"bisque", 255, 228, 196},
-  {"black",  0, 0, 0},
-  {"blanchedalmond", 255, 235, 205},
-  {"blue",  0, 0, 255},
-  {"blueviolet", 138, 43, 226},
-  {"brown", 165, 42, 42},
-  {"burlywood", 222, 184, 135},
-  {"cadetblue",  95, 158, 160},
-  {"chartreuse", 127, 255, 0},
-  {"chocolate", 210, 105, 30},
-  {"coral", 255, 127, 80},
-  {"cornflowerblue", 100, 149, 237},
-  {"cornsilk", 255, 248, 220},
-  {"crimson", 220, 20, 60},
-  {"cyan",  0, 255, 255},
-  {"darkblue",  0, 0, 139},
-  {"darkcyan",  0, 139, 139},
-  {"darkgoldenrod", 184, 134, 11},
-  {"darkgray", 169, 169, 169},
-  {"darkgreen",  0, 100, 0},
-  {"darkgrey", 169, 169, 169},
-  {"darkkhaki", 189, 183, 107},
-  {"darkmagenta", 139, 0, 139},
-  {"darkolivegreen",  85, 107, 47},
-  {"darkorange", 255, 140, 0},
-  {"darkorchid", 153, 50, 204},
-  {"darkred", 139, 0, 0},
-  {"darksalmon", 233, 150, 122},
-  {"darkseagreen", 143, 188, 143},
-  {"darkslateblue",  72, 61, 139},
-  {"darkslategray",  47, 79, 79},
-  {"darkslategrey",  47, 79, 79},
-  {"darkturquoise",  0, 206, 209},
-  {"darkviolet", 148, 0, 211},
-  {"deeppink", 255, 20, 147},
-  {"deepskyblue",  0, 191, 255},
-  {"dimgray", 105, 105, 105},
-  {"dimgrey", 105, 105, 105},
-  {"dodgerblue",  30, 144, 255},
-  {"firebrick", 178, 34, 34},
-  {"floralwhite", 255, 250, 240},
-  {"forestgreen",  34, 139, 34},
-  {"fuchsia", 255, 0, 255},
-  {"gainsboro", 220, 220, 220},
-  {"ghostwhite", 248, 248, 255},
-  {"gold", 255, 215, 0},
-  {"goldenrod", 218, 165, 32},
-  {"gray", 128, 128, 128},
-  {"grey", 128, 128, 128},
-  {"green",  0, 128, 0},
-  {"greenyellow", 173, 255, 47},
-  {"honeydew", 240, 255, 240},
-  {"hotpink", 255, 105, 180},
-  {"indianred", 205, 92, 92},
-  {"indigo",  75, 0, 130},
-  {"ivory", 255, 255, 240},
-  {"khaki", 240, 230, 140},
-  {"lavender", 230, 230, 250},
-  {"lavenderblush", 255, 240, 245},
-  {"lawngreen", 124, 252, 0},
-  {"lemonchiffon", 255, 250, 205},
-  {"lightblue", 173, 216, 230},
-  {"lightcoral", 240, 128, 128},
-  {"lightcyan", 224, 255, 255},
-  {"lightgoldenrodyellow", 250, 250, 210},
-  {"lightgray", 211, 211, 211},
-  {"lightgreen", 144, 238, 144},
-  {"lightgrey", 211, 211, 211},
-  {"lightpink", 255, 182, 193},
-  {"lightsalmon", 255, 160, 122},
-  {"lightseagreen",  32, 178, 170},
-  {"lightskyblue", 135, 206, 250},
-  {"lightslategray", 119, 136, 153},
-  {"lightslategrey", 119, 136, 153},
-  {"lightsteelblue", 176, 196, 222},
-  {"lightyellow", 255, 255, 224},
-  {"lime",  0, 255, 0},
-  {"limegreen",  50, 205, 50},
-  {"linen", 250, 240, 230},
-  {"magenta", 255, 0, 255},
-  {"maroon", 128, 0, 0},
-  {"mediumaquamarine", 102, 205, 170},
-  {"mediumblue",  0, 0, 205},
-  {"mediumorchid", 186, 85, 211},
-  {"mediumpurple", 147, 112, 219},
-  {"mediumseagreen",  60, 179, 113},
-  {"mediumslateblue", 123, 104, 238},
-  {"mediumspringgreen",  0, 250, 154},
-  {"mediumturquoise",  72, 209, 204},
-  {"mediumvioletred", 199, 21, 133},
-  {"midnightblue",  25, 25, 112},
-  {"mintcream", 245, 255, 250},
-  {"mistyrose", 255, 228, 225},
-  {"moccasin", 255, 228, 181},
-  {"navajowhite", 255, 222, 173},
-  {"navy",  0, 0, 128},
-  {"oldlace", 253, 245, 230},
-  {"olive", 128, 128, 0},
-  {"olivedrab", 107, 142, 35},
-  {"orange", 255, 165, 0},
-  {"orangered", 255, 69, 0},
-  {"orchid", 218, 112, 214},
-  {"palegoldenrod", 238, 232, 170},
-  {"palegreen", 152, 251, 152},
-  {"paleturquoise", 175, 238, 238},
-  {"palevioletred", 219, 112, 147},
-  {"papayawhip", 255, 239, 213},
-  {"peachpuff", 255, 218, 185},
-  {"peru", 205, 133, 63},
-  {"pink", 255, 192, 203},
-  {"plum", 221, 160, 221},
-  {"powderblue", 176, 224, 230},
-  {"purple", 128, 0, 128},
-  {"red", 255, 0, 0},
-  {"rosybrown", 188, 143, 143},
-  {"royalblue",  65, 105, 225},
-  {"saddlebrown", 139, 69, 19},
-  {"salmon", 250, 128, 114},
-  {"sandybrown", 244, 164, 96},
-  {"seagreen",  46, 139, 87},
-  {"seashell", 255, 245, 238},
-  {"sienna", 160, 82, 45},
-  {"silver", 192, 192, 192},
-  {"skyblue", 135, 206, 235},
-  {"slateblue", 106, 90, 205},
-  {"slategray", 112, 128, 144},
-  {"slategrey", 112, 128, 144},
-  {"snow", 255, 250, 250},
-  {"springgreen",  0, 255, 127},
-  {"steelblue",  70, 130, 180},
-  {"tan", 210, 180, 140},
-  {"teal",  0, 128, 128},
-  {"thistle", 216, 191, 216},
-  {"tomato", 255, 99, 71},
-  {"turquoise",  64, 224, 208},
-  {"violet", 238, 130, 238},
-  {"wheat", 245, 222, 179},
-  {"white", 255, 255, 255},
-  {"whitesmoke", 245, 245, 245},
-  {"yellow", 255, 255, 0},
-  {"yellowgreen", 154, 205, 50},
+};
+
+static const QHash<QString, rgb_t> color_table = {
+  {"aliceblue", {240, 248, 255}},
+  {"antiquewhite", {250, 235, 215}},
+  {"aqua", { 0, 255, 255}},
+  {"aquamarine", {127, 255, 212}},
+  {"azure", {240, 255, 255}},
+  {"beige", {245, 245, 220}},
+  {"bisque", {255, 228, 196}},
+  {"black", { 0, 0, 0}},
+  {"blanchedalmond", {255, 235, 205}},
+  {"blue", { 0, 0, 255}},
+  {"blueviolet", {138, 43, 226}},
+  {"brown", {165, 42, 42}},
+  {"burlywood", {222, 184, 135}},
+  {"cadetblue", { 95, 158, 160}},
+  {"chartreuse", {127, 255, 0}},
+  {"chocolate", {210, 105, 30}},
+  {"coral", {255, 127, 80}},
+  {"cornflowerblue", {100, 149, 237}},
+  {"cornsilk", {255, 248, 220}},
+  {"crimson", {220, 20, 60}},
+  {"cyan", { 0, 255, 255}},
+  {"darkblue", { 0, 0, 139}},
+  {"darkcyan", { 0, 139, 139}},
+  {"darkgoldenrod", {184, 134, 11}},
+  {"darkgray", {169, 169, 169}},
+  {"darkgreen", { 0, 100, 0}},
+  {"darkgrey", {169, 169, 169}},
+  {"darkkhaki", {189, 183, 107}},
+  {"darkmagenta", {139, 0, 139}},
+  {"darkolivegreen", { 85, 107, 47}},
+  {"darkorange", {255, 140, 0}},
+  {"darkorchid", {153, 50, 204}},
+  {"darkred", {139, 0, 0}},
+  {"darksalmon", {233, 150, 122}},
+  {"darkseagreen", {143, 188, 143}},
+  {"darkslateblue", { 72, 61, 139}},
+  {"darkslategray", { 47, 79, 79}},
+  {"darkslategrey", { 47, 79, 79}},
+  {"darkturquoise", { 0, 206, 209}},
+  {"darkviolet", {148, 0, 211}},
+  {"deeppink", {255, 20, 147}},
+  {"deepskyblue", { 0, 191, 255}},
+  {"dimgray", {105, 105, 105}},
+  {"dimgrey", {105, 105, 105}},
+  {"dodgerblue", { 30, 144, 255}},
+  {"firebrick", {178, 34, 34}},
+  {"floralwhite", {255, 250, 240}},
+  {"forestgreen", { 34, 139, 34}},
+  {"fuchsia", {255, 0, 255}},
+  {"gainsboro", {220, 220, 220}},
+  {"ghostwhite", {248, 248, 255}},
+  {"gold", {255, 215, 0}},
+  {"goldenrod", {218, 165, 32}},
+  {"gray", {128, 128, 128}},
+  {"grey", {128, 128, 128}},
+  {"green", { 0, 128, 0}},
+  {"greenyellow", {173, 255, 47}},
+  {"honeydew", {240, 255, 240}},
+  {"hotpink", {255, 105, 180}},
+  {"indianred", {205, 92, 92}},
+  {"indigo", { 75, 0, 130}},
+  {"ivory", {255, 255, 240}},
+  {"khaki", {240, 230, 140}},
+  {"lavender", {230, 230, 250}},
+  {"lavenderblush", {255, 240, 245}},
+  {"lawngreen", {124, 252, 0}},
+  {"lemonchiffon", {255, 250, 205}},
+  {"lightblue", {173, 216, 230}},
+  {"lightcoral", {240, 128, 128}},
+  {"lightcyan", {224, 255, 255}},
+  {"lightgoldenrodyellow", {250, 250, 210}},
+  {"lightgray", {211, 211, 211}},
+  {"lightgreen", {144, 238, 144}},
+  {"lightgrey", {211, 211, 211}},
+  {"lightpink", {255, 182, 193}},
+  {"lightsalmon", {255, 160, 122}},
+  {"lightseagreen", { 32, 178, 170}},
+  {"lightskyblue", {135, 206, 250}},
+  {"lightslategray", {119, 136, 153}},
+  {"lightslategrey", {119, 136, 153}},
+  {"lightsteelblue", {176, 196, 222}},
+  {"lightyellow", {255, 255, 224}},
+  {"lime", { 0, 255, 0}},
+  {"limegreen", { 50, 205, 50}},
+  {"linen", {250, 240, 230}},
+  {"magenta", {255, 0, 255}},
+  {"maroon", {128, 0, 0}},
+  {"mediumaquamarine", {102, 205, 170}},
+  {"mediumblue", { 0, 0, 205}},
+  {"mediumorchid", {186, 85, 211}},
+  {"mediumpurple", {147, 112, 219}},
+  {"mediumseagreen", { 60, 179, 113}},
+  {"mediumslateblue", {123, 104, 238}},
+  {"mediumspringgreen", { 0, 250, 154}},
+  {"mediumturquoise", { 72, 209, 204}},
+  {"mediumvioletred", {199, 21, 133}},
+  {"midnightblue", { 25, 25, 112}},
+  {"mintcream", {245, 255, 250}},
+  {"mistyrose", {255, 228, 225}},
+  {"moccasin", {255, 228, 181}},
+  {"navajowhite", {255, 222, 173}},
+  {"navy", { 0, 0, 128}},
+  {"oldlace", {253, 245, 230}},
+  {"olive", {128, 128, 0}},
+  {"olivedrab", {107, 142, 35}},
+  {"orange", {255, 165, 0}},
+  {"orangered", {255, 69, 0}},
+  {"orchid", {218, 112, 214}},
+  {"palegoldenrod", {238, 232, 170}},
+  {"palegreen", {152, 251, 152}},
+  {"paleturquoise", {175, 238, 238}},
+  {"palevioletred", {219, 112, 147}},
+  {"papayawhip", {255, 239, 213}},
+  {"peachpuff", {255, 218, 185}},
+  {"peru", {205, 133, 63}},
+  {"pink", {255, 192, 203}},
+  {"plum", {221, 160, 221}},
+  {"powderblue", {176, 224, 230}},
+  {"purple", {128, 0, 128}},
+  {"red", {255, 0, 0}},
+  {"rosybrown", {188, 143, 143}},
+  {"royalblue", { 65, 105, 225}},
+  {"saddlebrown", {139, 69, 19}},
+  {"salmon", {250, 128, 114}},
+  {"sandybrown", {244, 164, 96}},
+  {"seagreen", { 46, 139, 87}},
+  {"seashell", {255, 245, 238}},
+  {"sienna", {160, 82, 45}},
+  {"silver", {192, 192, 192}},
+  {"skyblue", {135, 206, 235}},
+  {"slateblue", {106, 90, 205}},
+  {"slategray", {112, 128, 144}},
+  {"slategrey", {112, 128, 144}},
+  {"snow", {255, 250, 250}},
+  {"springgreen", { 0, 255, 127}},
+  {"steelblue", { 70, 130, 180}},
+  {"tan", {210, 180, 140}},
+  {"teal", { 0, 128, 128}},
+  {"thistle", {216, 191, 216}},
+  {"tomato", {255, 99, 71}},
+  {"turquoise", { 64, 224, 208}},
+  {"violet", {238, 130, 238}},
+  {"wheat", {245, 222, 179}},
+  {"white", {255, 255, 255}},
+  {"whitesmoke", {245, 245, 245}},
+  {"yellow", {255, 255, 0}},
+  {"yellowgreen", {154, 205, 50}},
 };
 
 
 /*
  * Functions for converting human-readable colors to BBGGRR value.
- * Substantial optimization opportunities remain.
  */
-static int HexDigit(char hex)
-{
-  const char* Digits = "0123456789ABCDEF";
-  const char* digits = "0123456789abcdef";
-  const char* ofs = strchr(digits, hex);
-  if (ofs) {
-    return ofs-digits;
-  }
-
-  ofs = strchr(Digits, hex);
-  if (ofs) {
-    return ofs-Digits;
-  }
-  return 0;
-}
-
-static int HexByte(const char* hex)
-{
-  int b = (HexDigit(hex[0])<<4)+HexDigit(hex[1]);
-  return b;
-}
 
 /*
  * Given an input of the form:
@@ -219,31 +205,28 @@ static int HexByte(const char* hex)
  */
 
 int
-color_to_bbggrr(const char* cname)
+color_to_bbggrr(const QString& cname)
 {
-  char* ep;
-
-  int color_num = strtol(cname, &ep, 10);
+  bool ok;
+  int color_num = cname.toInt(&ok);
 
-  if (ep != cname) {
+  if (ok) {
     return color_num;
   }
 
-  if (cname[0] == '#') {
-    color_num = (HexByte(cname+1)) +      // red
-                (HexByte(cname+3)<<8) +   // green
-                (HexByte(cname+5)<<16);   // blue
-    return color_num;
+  static const QRegularExpression re("^#(?<red>[[:xdigit:]]{2})(?<green>[[:xdigit:]]{2})(?<blue>[[:xdigit:]]{2})$");
+  assert(re.isValid());
+  if (QRegularExpressionMatch match = re.match(cname); match.hasMatch()) {
+    return (match.captured("red").toInt(nullptr, 16) +
+            (match.captured("green").toInt(nullptr, 16) << 8) +
+            (match.captured("blue").toInt(nullptr, 16) << 16));
   }
 
-  for (auto i : color_table) {
-    if (0 == case_ignore_strcmp(cname, i.cn)) {
-      return (i.b << 16) +
-             (i.g << 8) +
-              i.r;
-    }
+  if (color_table.contains(cname)) {
+    auto entry = color_table.value(cname);
+    return (entry.b << 16) + (entry.g << 8) + entry.r;
   }
 
-  fatal("unrecognized color name %s\n", cname);
+  fatal("unrecognized color name %s\n", qPrintable(cname));
   return -1;
 }
index 1a94e465ebfa2a999f991bf7578676b95d317591..de5410ca6897010c61c101f5834538c0db6934d2 100644 (file)
@@ -8,6 +8,9 @@ compare ${TMPDIR}/ozi.wpt ${REFERENCE}
 # Same, but with colors set
 gpsbabel -i geo -f ${REFERENCE}/geocaching.loc  -o ozi,wptfgcolor=#de0000,wptbgcolor=red -F ${TMPDIR}/ozi-color.wpt
 compare ${TMPDIR}/ozi-color.wpt ${REFERENCE}
+gpsbabel -i geo -f ${REFERENCE}/geocaching.loc  -o ozi,wptfgcolor=222,wptbgcolor=red -F ${TMPDIR}/ozi-color.wpt
+compare ${TMPDIR}/ozi-color.wpt ${REFERENCE}
+
 
 # Test Ozi routes.
 gpsbabel -i ozi -f ${REFERENCE}/route/ozi.rte -o gpx -F ${TMPDIR}/ozi~gpx.gpx